#include "HttpConnection.hpp"
#include "LogicSystem.h"
#include "UrlCoding.h"
#include "Logger.hpp"

// TODO:全部改造成asio相关处理，参考链接：https://gitbookcpp.llfc.club/sections/cpp/boost/asio22.html
HttpConnection::HttpConnection(boost::asio::io_context &ioc) : _socket(ioc)
{
}

void HttpConnection::Start()
{
    auto self = shared_from_this();
    // 读数据
    // http::async_read(_socket, _buffer, _request, [self](beast::error_code ec, std::size_t bytes_transferred) {
    //     try
    //     {
    //         if (ec)
    //         { // 出现异常则重新监听
    //             std::cerr << "http read err is " << ec.what() << std::endl;
    //             // 不需要再次Start()来监听请求，因为在CServer中会重新调用Start()
    //             //  self->Start();
    //             return;
    //         }

    //         // 处理请求
    //         boost::ignore_unused(bytes_transferred);
    //         self->HandleReq();
    //         // 启动超时监测
    //         self->CheckDeadline();
    //     }
    //     catch (const std::exception &e)
    //     {
    //         std::cerr << e.what() << '\n';
    //     }
    // });

    // asio处理请求
    _socket.async_receive(_buffer, [self](boost::system::error_code ec, std::size_t bytes_transferred) {
        try
        {
            if (ec)
            { // 出现异常则重新监听
                std::cerr << "http read err is " << ec.what() << std::endl;
                // 不需要再次Start()来监听请求，因为在CServer中会重新调用Start()
                //  self->Start();
                return;
            }

            // 处理请求
            boost::ignore_unused(bytes_transferred);
            self->HandleReq();
            // 启动超时监测
            self->CheckDeadline();
        }
        catch (const std::exception &e)
        {
            // std::cerr << e.what() << '\n';
            if (ec != boost::asio::error::eof)
                LOG_ERROR("http read err is {}", ec.what());
            else
                LOG_INFO("http connection closed");
        }
    });
}

void HttpConnection::HandleReq()
{
    // 设置版本
    _response.version(_request.version());
    // 设置为短链接（HTTP是短链接）
    _response.keep_alive(false);

    // 处理get请求
    if (_request.method() == http::verb::get) // 如果是get请求
    {
        PreParseGetParam(); // url预处理，获取请求参数
        // 调用LogicSystem处理get请求
        bool success = LogicSystem::GetInstance()->HandleGetReq(_get_url, shared_from_this());
        // 返回响应
        if (!success)
        {
            HandleNotFound();
        }

        HandleSuccess();
        return;
    }

    // post请求
    if (_request.method() == http::verb::post) // 如果是post请求
    {
        bool success = LogicSystem::GetInstance()->HandlePostReq(_request.target(), shared_from_this());
        // 返回响应
        if (!success)
        {
            HandleNotFound();
            return;
        }

        HandleSuccess();
        return;
    }

    // TODO:如果是其他请求。。。
}

void HttpConnection::CheckDeadline()
{
    auto self = shared_from_this();
    _deadline.async_wait([self](beast::error_code ec) {
        if (!ec)
        {
            self->_socket.close(ec);
        }
    });
}

void HttpConnection::WriteResponse()
{
    auto self = shared_from_this();
    _response.content_length(_response.body().size());
    // http::async_write(_socket, _response, [self](beast::error_code ec, std::size_t bytes_transferred) {
    //     self->_socket.shutdown(tcp::socket::shutdown_send, ec);
    //     self->_deadline.cancel(); // 取消定时器
    // });
    _socket.async_send(_response.body(), [self](beast::error_code ec, std::size_t bytes_transferred) {
        self->_socket.shutdown(tcp::socket::shutdown_send, ec);
        self->_deadline.cancel(); // 取消定时器
    });
}

void HttpConnection::HandleNotFound()
{
    _response.result(http::status::not_found);
    // _response.set(http::field::content_type, "text/plain");  //交由HandleReq()处理
    // beast::ostream(_response.body()) << "url not found\r\n";

    WriteResponse();
}

void HttpConnection::HandleSuccess()
{
    _response.result(http::status::ok);
    // _response.set(http::field::content_type, "application/json");    //交由HandleGetReq()来决定返回什么
    // _response.content_length(_response.body().size());
    WriteResponse();
    return;
}

tcp::socket &HttpConnection::GetSocket()
{
    return _socket;
}

void HttpConnection::PreParseGetParam()
{
    // 提取URI
    auto uri = _request.target();
    auto param_pos = uri.find('?');     // 查找'?'开始下标
    if (param_pos == std::string::npos) // 找不到'?'
    {
        _get_url = uri;
        std::cout << "url is " << _get_url << std::endl;
        size_t pos;
        if (pos = _get_url.find("static/")) // 静态资源的请求处理
        {
            std::string res_path = _get_url.substr(pos + 7); // 截取/static/后面的路径
            res_path = UrlDecode(res_path);
            _get_url.erase(pos + 6, _get_url.size() - pos); // 把/static后面的路径删掉
            // std::cout << "-------------------------url is: " << _get_url << std::endl;
            _get_params["res_path"] = res_path; // 将路径存放到_get_params中
        }
        return;
    }

    // 提取参数
    // 先提取请求路径
    _get_url = uri.substr(0, param_pos++);
    // 提取请求参数
    //  std::string temp_str = uri.substr(param_pos);
    std::string temp_str = uri.substr(param_pos);
    std::string key;
    std::string val;
    size_t pos = 0;
    while ((pos = temp_str.find('&')) != std::string::npos)
    {
        auto pair = temp_str.substr(0, pos);
        size_t eq_pos = pair.find('=');
        if (eq_pos != std::string::npos)
        {
            key = UrlDecode(pair.substr(0, eq_pos)); // 假设有 url_decode 函数来处理URL解码
            val = UrlDecode(pair.substr(eq_pos + 1));
            _get_params[key] = val;
        }
        temp_str.erase(0, pos + 1);
    }
    // 处理最后一个参数对（如果没有 & 分隔符）
    if (!temp_str.empty())
    {
        size_t eq_pos = temp_str.find('=');
        if (eq_pos != std::string::npos)
        {
            key = UrlDecode(temp_str.substr(0, eq_pos));
            val = UrlDecode(temp_str.substr(eq_pos + 1));
            _get_params[key] = val;
        }
    }
}